
import { UtilsHelper } from "utils/position/UtilsHelper";
import { StructureEntity } from "../StructureEntity";
import { PositionHelper } from "utils/position/PositionHelper";
import { StationNetwork } from "GameLoop/Path/StationNetwork";
 


export abstract class MinerialEntity<T extends IMinerialMemory=IMinerialMemory,V extends IRoomModuleInitializer=IRoomModuleInitializer>  extends StructureEntity<T,V>  
{
     
    protected workPos!:RoomPosition;
    protected _pickupPos!:RoomPosition[];// 拾取的坐标
    protected _path!:RoomPosition[];    // 路径
    protected _basepos!:RoomPosition;
    protected _source!:{id:Id<Mineral>,pos:RoomPosition} 
    public updateState(state:number)
    {
        this.getNodeMemory().state = state;
         
    }
    protected initPath(nodememory:T)
    {
   
        if(!nodememory.pathkey || !StationNetwork.getInstance.getPathCacheByKey(nodememory.pathkey))
        {
            const centerpos = this.lordRoom.getNodeMemory().center as [number,number];
            const startpos = PositionHelper.Create({x:centerpos[0],y:centerpos[1],roomName:this.lordRoom.name})
            const path = StationNetwork.getInstance.searchRoad(startpos,{pos:this.BasePosition,range:1},{});
            if(!path||path.path.length ==0 )
            {
                throw new Error(` 路径初始化失败: ${this.GUID()}`);
            }
            const cacheret = StationNetwork.getInstance.addRoadCache(path.path[0],path);
            nodememory.pathkey = cacheret.key
        }
        if( nodememory.pathkey)
        {
            const cacheret = StationNetwork.getInstance.getPathCacheByKey(nodememory.pathkey);
            if(cacheret)
            {
                this._path = UtilsHelper.deserializePathCache(cacheret.path);
            }
        }
    }
    public initAttributes(): void 
    {
        super.initAttributes();
        const nodememory = this.getNodeMemory();
        if(!nodememory.skey)
        {
            const obj = Game.getObjectById( this.GUID() as Id<Mineral>);
            if(obj)
            {
                nodememory.skey = UtilsHelper.serializeObject(obj);
                nodememory.minerialtype = obj.mineralType;
            }
            else 
            {
                if(Game.rooms[this.BasePosition.roomName])
                {
                    const minerial = this.BasePosition.lookFor(LOOK_MINERALS)[0];
                    nodememory.skey = UtilsHelper.serializeObject(minerial);
                    nodememory.minerialtype = minerial?.mineralType;
                }
                else 
                {
                    // nodememory.skey = UtilsHelper.serializeObject ({id:nodememory.source.id as Id<Source>,pos:nodememory.source} as any);
                }
            }
            
        }
        
        this._source = UtilsHelper.deSerializeObject(nodememory.skey)
        this._basepos = PositionHelper.Create(this._source.pos);
        if(!nodememory.minerialtype)
        {
            nodememory.minerialtype = this.getMinerial()?.mineralType;
        }
       
        this.initPath(nodememory);
        this._pickupPos = this.BasePosition.getFreeSpace(1);
        const container = this.getContainer() ;
        if(container  )
        {
            this.workPos = container.pos;
        }
        else
        {
            this.workPos = _.min(this._pickupPos,e=>e.distance(this._path[ this._path .length-1]));;
        }
        this.updateContainer();
        // Memory.Debug["workpos_"+this.GUID()] = this.workPos;
    }
    public get region():string{
       
        return Memory.rooms[this._initializer.roomName].lord
        
    }
    public get MinerialType()
    {
        return this.getNodeMemory().minerialtype
    }
    public updateMemory(): void 
    {
        // 更新container 和link
         // 更新container
        this.updateContainer();
    }
    private updateContainer()
    {
        if(!this.getNodeMemory().containerId ||(this.room && !Game.getObjectById(this.getNodeMemory().containerId as any)))
        {
            this.getNodeMemory().containerId =  PositionHelper.lookFor(LOOK_STRUCTURES, this.workPos).filter(e=>e.structureType == STRUCTURE_CONTAINER)[0]?.id as Id<StructureContainer>;
        }  
    }
    public getMinerial(): Mineral 
    {
        return Game.getObjectById(this._source.id) as Mineral
        // return Game.getObjectById(this.getNodeMemory().source.id as Id<Mineral>) as Mineral
        // throw new Error("Method not implemented.");
    }

    public getContainer()
    {
        return Game.getObjectById(this.getNodeMemory().containerId as Id<StructureContainer> )
    }
    public getPickUpItem(resourceType?:ResourceConstant ,amount?:number)
    {
        if(!Game.rooms[this.roomName])
        {
            return []
        }
        if(resourceType)
        {
            return _.flatten(this._pickupPos.map(
                e=>PositionHelper.lookFor(LOOK_RESOURCES,e).filter(i=>i.amount>=(amount?amount:0) && i.resourceType == resourceType)
                ));
        }
       
        return _.flatten(this._pickupPos.map(
            e=>PositionHelper.lookFor(LOOK_RESOURCES,e).filter(i=>i.amount>=(amount?amount:0) )
            ));
    }
    /**
     * source周围一圈的空闲位置
     * @returns 
     */
    public getAroundPos()
    {
        return this._pickupPos
    }

    public getWorkPosition()
    {
        return this.workPos;
    }
    /**
     * 获取从房间储存点到source的路径
     */
    public getPath():RoomPosition[]
    {
        return this._path
    }
    
}
